package com.study.aop.theory.myaop;

import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * * ioc容器，此处功能等价于IocContainer
 * * 只不过api接口表现方式更接近于Spring
 *
 * @author: chenhs
 * @date: Created in 8:12 2020/2/6
 **/
public class MikeApplicationContext implements ApplicationContext {

    private Map<String, Class<?>> beanDefinitionMap = new ConcurrentHashMap<>(256);

    private Aspect aspect;
    
    @Override
    public void registerBeanDefinition(String beanName, Class<?> beanClass) {
        this.beanDefinitionMap.put(beanName, beanClass);
    }

    @Override
    public Object getBean(String beanName) throws Throwable {
        Object bean = createInstance(beanName);
        bean = proxyEnhance(bean);
        return bean;
    }

    private Object createInstance(String beanName) throws Throwable {
        return this.beanDefinitionMap.get(beanName).newInstance();
    }

    private Object proxyEnhance(Object bean) {
        if (this.aspect != null && bean.getClass().getName().matches(this.aspect.getPointcut().getClassPattern())) {
            return Proxy.newProxyInstance(bean.getClass().getClassLoader()
                    , bean.getClass().getInterfaces()
                    , new AopInvocationHandler(bean, aspect));
        }
        return bean;
    }

    @Override
    public void setAspect(Aspect aspect) {
        this.aspect = aspect;
    }
}
